LIBRARY IEEE;             
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

USE WORK.TYPES.ALL;

entity ID_EX is
    port(
        clock,reset : IN  STD_LOGIC;

        --Sinais de passagem
        NextPc_in   : IN  MEMADDR;
        NextPc_out  : OUT MEMADDR;

        --Sinais do controle:
        RegDst_in   : IN STD_LOGIC;
        ALUSrc_in   : IN STD_LOGIC;
        MemtoReg_in : IN STD_LOGIC;
        RegWrite_in : IN STD_LOGIC;
        MemRead_in  : IN STD_LOGIC;
        MemWrite_in : IN STD_LOGIC;
        Branch_in   : IN STD_LOGIC;
        ALUop_in    : IN STD_LOGIC_VECTOR( 1 DOWNTO 0 );

        ALUSrc_out   : OUT STD_LOGIC;
        MemtoReg_out : OUT STD_LOGIC;
        RegWrite_out : OUT STD_LOGIC;
        MemRead_out  : OUT STD_LOGIC;
        MemWrite_out : OUT STD_LOGIC;
        Branch_out   : OUT STD_LOGIC;
        ALUop_out    : OUT STD_LOGIC_VECTOR( 1 DOWNTO 0 );

        --Dados da decodificação:
        read_data_1_in  : IN MEMDATA;
        read_data_2_in  : IN MEMDATA;
        Sign_extend_in  : IN MEMDATA;

        read_data_1_out : OUT MEMDATA;
        read_data_2_out : OUT MEMDATA;
        Sign_extend_out : OUT MEMDATA;

        --Endereço de escrita:
        WrAddr_0    : IN  REGADDR;
        WrAddr_1    : IN  REGADDR;
        WrAddr_out  : OUT REGADDR
    );
end ID_EX;

architecture pipe of ID_EX is
    signal RegDst_aux   : STD_LOGIC;
    signal WrAddr_0_aux : REGADDR;
    signal WrAddr_1_aux : REGADDR;
begin
    --Mux com o endereço de escrita:
    WrAddr_out <= WrAddr_1_aux  WHEN RegDst_aux = '1'
                                ELSE WrAddr_0_aux;
    process (clock)
    begin
        if rising_edge(clock) then
            --Passagem:
            NextPc_out   <= NextPc_in; 
            --Controle:
            RegDst_aux   <= RegDst_in;
            ALUSrc_out   <= ALUSrc_in;
            MemtoReg_out <= MemtoReg_in;
            RegWrite_out <= RegWrite_in;
            MemRead_out  <= MemRead_in;
            MemWrite_out <= MemWrite_in;
            Branch_out   <= Branch_in;
            ALUop_out    <= ALUop_in;
            --Decodificação:
            read_data_1_out <= read_data_1_in;
            read_data_2_out <= read_data_2_in;
            Sign_extend_out <= Sign_extend_in;
            --Endereço de escrita:
            WrAddr_0_aux    <= WrAddr_0;
            WrAddr_1_aux    <= WrAddr_1;
        end if;
    end process;
end pipe;


